package com.kaifamiao.mapper;

import com.kaifamiao.model.Account;
import com.kaifamiao.provider.AccountProvider;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

/**
 * @author lucien-ma
 * @date 2021/8/17
 * @apiNote
 */
// mybatis 基于注解方式实现配置二级缓存
@CacheNamespace(blocking = true)
public interface IAccountMapper {

    /**
     * 一对一联表查询，并设置为懒加载
     * @return
     */
    @Select("select * from account")
    @Results(id = "accountMap",value = {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "uid", property = "uid"),
            @Result(column = "money", property = "money"),
            @Result(column = "uid", property = "user",
            one = @One(select = "com.kaifamiao.mapper.IUserMapper.findById", fetchType = FetchType.LAZY))
    })
    List<Account> findAllWithUser();

    /**
     * 在 IAccountMapper 中实现一对多联表查询，
     * 需要用到这个查询方法
     * @param uid
     * @return
     */
    @Select("select * from account where uid = #{id}")
    Account selectByUid(Integer uid);

    /**
     * 根据账户编号查询账户信息及其所属用户信息
     * @param id
     * @return
     */
    @Select("select * from account where id = #{id}")
    @ResultMap("accountMap")
    Account findByIdWithUser(Integer id);

    /**
     * 使用 <script></script> 标签实现动态 SQL 查询
     */
    @Select("<script>" +
            "select * from account" +
            "<where>" +
            "<if test = 'id != null'>" +
            " and id = #{id}" +
            "</if>" +
            "<if test = 'uid != null'>" +
            " and uid = #{uid}" +
            "</if>" +
            "<if test = 'money != null'>" +
            " and money = #{money}" +
            "</if>" +
            "</where>" +
            "</script>")
    List<Account> findSelectiveByScript(Account account);

    /**
     * 使用 @SelectProvider 注解，结合 ***Provider类实现动态 sql 查询
     * @param account
     * @return
     */
    @SelectProvider(type = AccountProvider.class, method = "findSelective")
    List<Account> findSelectiveByProvider(Account account);

    /**
     * 使用<script></script> 标签实现动态 SQL 插入数据
     * @param account
     * @return
     */
    @Insert("<script>" +
            "insert into account" +
            "<trim prefix='(' suffix=')' suffixOverrides=','>" +
            "<if test = 'id != null'>" +
            "id," +
            "</if>" +
            "<if test = 'uid != null'>" +
            "uid," +
            "</if>" +
            "<if test = 'money != null'>" +
            "money," +
            "</if>" +
            "</trim>" +
            "<trim prefix=' values(' suffix=')' suffixOverrides=','>" +
            "<if test = 'id != null'>" +
            "#{id}," +
            "</if>" +
            "<if test = 'uid != null'>" +
            "#{uid}," +
            "</if>" +
            "<if test = 'money != null'>" +
            "#{money}," +
            "</if>" +
            "</trim>" +
            "</script>")
    int insertSelectiveByScript(Account account);

    /**
     * 用 @InsertProvider 注解实现动态 SQL 插入数据
     * @param account
     * @return
     */
    @InsertProvider(type = AccountProvider.class, method = "insertSelective" )
    int insertSelectiveByProvider(Account account);

    /**
     * 用 @UpdateProvider 注解实现动态 SQL 修改数据
     * @param account
     * @return
     */
    @UpdateProvider(type = AccountProvider.class, method = "updateSelective")
    int updateSelectiveByProvider(Account account);

    /**
     *使用 @ DeleteProvider 批量删除数据
     * @param ids
     * @return
     */
    @DeleteProvider(type = AccountProvider.class, method = "deleteAccounts")
    int deleteAccountsByProvider(Integer... ids);
}
